#include "crc16.h"


/* crc16-IBM 8005 */
static const uint16_t crc_table[] = {
    0x0000u, 0x8005u, 0x800fu, 0x000au, 0x801bu, 0x001eu, 0x0014u, 0x8011u,
    0x8033u, 0x0036u, 0x003cu, 0x8039u, 0x0028u, 0x802du, 0x8027u, 0x0022u,
    0x8063u, 0x0066u, 0x006cu, 0x8069u, 0x0078u, 0x807du, 0x8077u, 0x0072u,
    0x0050u, 0x8055u, 0x805fu, 0x005au, 0x804bu, 0x004eu, 0x0044u, 0x8041u,
    0x80c3u, 0x00c6u, 0x00ccu, 0x80c9u, 0x00d8u, 0x80ddu, 0x80d7u, 0x00d2u,
    0x00f0u, 0x80f5u, 0x80ffu, 0x00fau, 0x80ebu, 0x00eeu, 0x00e4u, 0x80e1u,
    0x00a0u, 0x80a5u, 0x80afu, 0x00aau, 0x80bbu, 0x00beu, 0x00b4u, 0x80b1u,
    0x8093u, 0x0096u, 0x009cu, 0x8099u, 0x0088u, 0x808du, 0x8087u, 0x0082u,
    0x8183u, 0x0186u, 0x018cu, 0x8189u, 0x0198u, 0x819du, 0x8197u, 0x0192u,
    0x01b0u, 0x81b5u, 0x81bfu, 0x01bau, 0x81abu, 0x01aeu, 0x01a4u, 0x81a1u,
    0x01e0u, 0x81e5u, 0x81efu, 0x01eau, 0x81fbu, 0x01feu, 0x01f4u, 0x81f1u,
    0x81d3u, 0x01d6u, 0x01dcu, 0x81d9u, 0x01c8u, 0x81cdu, 0x81c7u, 0x01c2u,
    0x0140u, 0x8145u, 0x814fu, 0x014au, 0x815bu, 0x015eu, 0x0154u, 0x8151u,
    0x8173u, 0x0176u, 0x017cu, 0x8179u, 0x0168u, 0x816du, 0x8167u, 0x0162u,
    0x8123u, 0x0126u, 0x012cu, 0x8129u, 0x0138u, 0x813du, 0x8137u, 0x0132u,
    0x0110u, 0x8115u, 0x811fu, 0x011au, 0x810bu, 0x010eu, 0x0104u, 0x8101u,
    0x8303u, 0x0306u, 0x030cu, 0x8309u, 0x0318u, 0x831du, 0x8317u, 0x0312u,
    0x0330u, 0x8335u, 0x833fu, 0x033au, 0x832bu, 0x032eu, 0x0324u, 0x8321u,
    0x0360u, 0x8365u, 0x836fu, 0x036au, 0x837bu, 0x037eu, 0x0374u, 0x8371u,
    0x8353u, 0x0356u, 0x035cu, 0x8359u, 0x0348u, 0x834du, 0x8347u, 0x0342u,
    0x03c0u, 0x83c5u, 0x83cfu, 0x03cau, 0x83dbu, 0x03deu, 0x03d4u, 0x83d1u,
    0x83f3u, 0x03f6u, 0x03fcu, 0x83f9u, 0x03e8u, 0x83edu, 0x83e7u, 0x03e2u,
    0x83a3u, 0x03a6u, 0x03acu, 0x83a9u, 0x03b8u, 0x83bdu, 0x83b7u, 0x03b2u,
    0x0390u, 0x8395u, 0x839fu, 0x039au, 0x838bu, 0x038eu, 0x0384u, 0x8381u,
    0x0280u, 0x8285u, 0x828fu, 0x028au, 0x829bu, 0x029eu, 0x0294u, 0x8291u,
    0x82b3u, 0x02b6u, 0x02bcu, 0x82b9u, 0x02a8u, 0x82adu, 0x82a7u, 0x02a2u,
    0x82e3u, 0x02e6u, 0x02ecu, 0x82e9u, 0x02f8u, 0x82fdu, 0x82f7u, 0x02f2u,
    0x02d0u, 0x82d5u, 0x82dfu, 0x02dau, 0x82cbu, 0x02ceu, 0x02c4u, 0x82c1u,
    0x8243u, 0x0246u, 0x024cu, 0x8249u, 0x0258u, 0x825du, 0x8257u, 0x0252u,
    0x0270u, 0x8275u, 0x827fu, 0x027au, 0x826bu, 0x026eu, 0x0264u, 0x8261u,
    0x0220u, 0x8225u, 0x822fu, 0x022au, 0x823bu, 0x023eu, 0x0234u, 0x8231u,
    0x8213u, 0x0216u, 0x021cu, 0x8219u, 0x0208u, 0x820du, 0x8207u, 0x0202u
};

/* 读卡器crc校验 初始值为 0xffff */
uint16_t Crc16(uint16_t crc, const uint8_t *buf, int32_t len) {
	int32_t i;
    for(i = 0; i < len; i++) {
        crc = (uint16_t)((uint16_t)(crc << 8u) ^ crc_table[((uint16_t)(crc >> 8u) ^ *buf++) & 0x00FFu]);
    }
    return crc;
}
